#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from os import path
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import yaml

from logs.logger import logger
from utils import utils


class CredentialBox():
    IV = b'1'*16
    MODE = AES.MODE_CBC
    KEY = b'kiwisec-cli-'.ljust(16, b'*')
    @classmethod
    def encrypt(cls, cred):
        enc = AES.new(cls.KEY, cls.MODE, cls.IV)
        data = enc.encrypt(pad(cred.encode('latin1'), 16))
        return data.hex()
    @classmethod
    def decrypt(cls, cred):
        enc = AES.new(cls.KEY, cls.MODE, cls.IV)
        data = enc.decrypt(bytes.fromhex(cred))
        data = unpad(data, 16)
        data = data.decode('latin1')
        return data


class Configer(metaclass=utils.SingletonThreadSafe):
    def __init__(self):
        self.conf_path = os.path.join(self._build_confdir(), '.kcliconf.dat')
        conf = {'config':{}}
        if path.exists(self.conf_path):
            with open(self.conf_path, 'r') as f:
                conf = yaml.safe_load(f.read())
        self.conf = conf['config']
        # logger.info(f'[+] KCLI config: {conf}')

    def _build_confdir(self):
        base_dir = os.path.dirname(os.path.abspath(__file__))  
        data_dir = os.path.join(base_dir, 'data')
        if not path.exists(data_dir):
            os.makedirs(data_dir)
        return data_dir

    def get_cred(self):
        key = 'cred'
        if key not in self.conf:
            return '', ''
        cred = self.conf[key]
        cred = CredentialBox.decrypt(cred)
        arr = cred.split(':')
        username = arr[0]
        password = arr[1]
        return username, password

    def set_cred(self, username, password):
        cred = ':'.join([username, password])
        cred = CredentialBox.encrypt(cred)
        self.conf['cred'] = cred
        self.update()

    def get(self, name):
        return self.conf[name] if name in self.conf else None

    def set(self, name, value):
        self.conf[name] = value
        return

    def update(self):
        logger.info('[+] Update config ok')
        with open(self.conf_path, 'w') as f:
            yaml.dump({'config':self.conf}, f)

def config():
    return Configer()